using System.Collections;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

namespace MaterialUI
{
	[AddComponentMenu("MaterialUI/Overscroll Config", 50)]
	public class OverscrollConfig : MonoBehaviour, IInitializePotentialDragHandler, IEventSystemHandler
	{
		[SerializeField]
		private Color m_OverscrollColor = new Color(0f, 0f, 0f, 0.25f);

		[SerializeField]
		private float m_OverscrollScale = 1f;

		private static Sprite overscrollSprite;

		private readonly GameObject[] m_OverscrollObjects = new GameObject[4];

		private readonly RectTransform[] m_OverscrollRectTransforms = new RectTransform[4];

		private readonly Image[] m_OverscrollImages = new Image[4];

		private RectTransform m_RectTransform;

		private ScrollRect m_ScrollRect;

		private readonly bool[] m_PointerDown = new bool[4];

		private Vector2 m_ScrollPosition;

		private Vector2 m_LastScrollPosition;

		private Vector2 m_Size;

		private bool m_ScrollVertical;

		private bool m_ScrollHorizontal;

		private readonly int[] m_EdgeAnims = new int[4];

		private readonly float[] m_EdgeAnimsCurrent = new float[4];

		private readonly float[] m_EdgeAnimsPower = new float[4];

		private readonly float[] m_EdgeAnimsStartTime = new float[4];

		private readonly float[] m_EdgeAnimsDeltaTime = new float[4];

		private float m_EdgeAnimDuration = 0.3f;

		private readonly float[] m_OverscrollAmounts = new float[4];

		private readonly float[] m_OverscrollPositions = new float[4];

		private Vector2 m_PointerDownPosition;

		private readonly float[] m_PointerBaseAmounts = new float[4];

		private int m_PointerCount;

		public Color overscrollColor
		{
			get
			{
				return m_OverscrollColor;
			}
			set
			{
				m_OverscrollColor = value;
				for (int i = 0; i < m_OverscrollObjects.Length; i++)
				{
					if (m_OverscrollObjects[i] != null && m_OverscrollObjects[i].GetComponent<Image>() != null)
					{
						m_OverscrollObjects[i].GetComponent<Image>().color = m_OverscrollColor;
					}
				}
			}
		}

		public float overscrollScale
		{
			get
			{
				return m_OverscrollScale;
			}
			set
			{
				m_OverscrollScale = value;
			}
		}

		private void Start()
		{
			Setup();
		}

		private void CreateOverscroll(int i)
		{
			if (!overscrollSprite)
			{
				overscrollSprite = Resources.Load<Sprite>("Overscroll");
			}
			m_OverscrollObjects[i] = new GameObject
			{
				name = "Overscroll"
			};
			m_OverscrollImages[i] = m_OverscrollObjects[i].AddComponent<Image>();
			m_OverscrollImages[i].sprite = overscrollSprite;
			m_OverscrollImages[i].color = m_OverscrollColor;
			m_OverscrollRectTransforms[i] = m_OverscrollObjects[i].GetComponent<RectTransform>();
			m_OverscrollRectTransforms[i].SetParent(base.transform);
			Vector2 sizeDelta = default(Vector2);
			Vector2 anchorMin = default(Vector2);
			Vector2 anchorMax = default(Vector2);
			Vector3 localEulerAngles = default(Vector3);
			switch (i)
			{
			case 0:
			{
				Vector2 sizeDelta5 = m_OverscrollRectTransforms[i].sizeDelta;
				sizeDelta = new Vector2(0f, sizeDelta5.y);
				anchorMin = new Vector2(0f, 0.5f);
				anchorMax = new Vector2(0f, 0.5f);
				localEulerAngles = new Vector3(0f, 0f, 270f);
				break;
			}
			case 1:
			{
				Vector2 sizeDelta4 = m_OverscrollRectTransforms[i].sizeDelta;
				sizeDelta = new Vector2(0f, sizeDelta4.y);
				anchorMin = new Vector2(1f, 0.5f);
				anchorMax = new Vector2(1f, 0.5f);
				localEulerAngles = new Vector3(0f, 0f, 90f);
				break;
			}
			case 2:
			{
				Vector2 sizeDelta3 = m_OverscrollRectTransforms[i].sizeDelta;
				sizeDelta = new Vector2(0f, sizeDelta3.y);
				anchorMin = new Vector2(0.5f, 1f);
				anchorMax = new Vector2(0.5f, 1f);
				localEulerAngles = new Vector3(0f, 0f, 180f);
				break;
			}
			case 3:
			{
				Vector2 sizeDelta2 = m_OverscrollRectTransforms[i].sizeDelta;
				sizeDelta = new Vector2(0f, sizeDelta2.y);
				anchorMin = new Vector2(0.5f, 0f);
				anchorMax = new Vector2(0.5f, 0f);
				localEulerAngles = new Vector3(0f, 0f, 0f);
				break;
			}
			}
			m_OverscrollRectTransforms[i].position = Vector3.zero;
			m_OverscrollRectTransforms[i].sizeDelta = sizeDelta;
			m_OverscrollRectTransforms[i].anchorMin = anchorMin;
			m_OverscrollRectTransforms[i].anchorMax = anchorMax;
			m_OverscrollRectTransforms[i].pivot = new Vector2(0.5f, 0f);
			m_OverscrollRectTransforms[i].localEulerAngles = localEulerAngles;
			m_OverscrollRectTransforms[i].localScale = Vector3.one;
			CanvasGroup addComponent = m_OverscrollRectTransforms[i].gameObject.GetAddComponent<CanvasGroup>();
			addComponent.alpha = 1f;
			addComponent.blocksRaycasts = false;
			addComponent.interactable = false;
			addComponent.ignoreParentGroups = true;
		}

		public void Setup()
		{
			for (int i = 0; i < m_OverscrollObjects.Length; i++)
			{
				UnityEngine.Object.Destroy(m_OverscrollObjects[i]);
			}
			m_RectTransform = base.gameObject.GetAddComponent<RectTransform>();
			m_ScrollRect = GetComponent<ScrollRect>();
			if (m_ScrollRect.movementType != ScrollRect.MovementType.Clamped)
			{
				base.enabled = false;
				return;
			}
			Canvas.ForceUpdateCanvases();
			int scrollVertical;
			if (m_ScrollRect.vertical)
			{
				Vector2 properSize = m_RectTransform.GetProperSize();
				float y = properSize.y;
				Vector2 properSize2 = m_ScrollRect.content.GetProperSize();
				scrollVertical = ((y < properSize2.y) ? 1 : 0);
			}
			else
			{
				scrollVertical = 0;
			}
			m_ScrollVertical = ((byte)scrollVertical != 0);
			int scrollHorizontal;
			if (m_ScrollRect.horizontal)
			{
				Vector2 properSize3 = m_RectTransform.GetProperSize();
				float x = properSize3.x;
				Vector2 properSize4 = m_ScrollRect.content.GetProperSize();
				scrollHorizontal = ((x < properSize4.x) ? 1 : 0);
			}
			else
			{
				scrollHorizontal = 0;
			}
			m_ScrollHorizontal = ((byte)scrollHorizontal != 0);
			if ((bool)GetComponent<VerticalScrollLayoutElement>())
			{
				StartCoroutine(GetDelayedSize());
			}
			else
			{
				m_Size = m_RectTransform.GetProperSize();
			}
			if (m_ScrollHorizontal)
			{
				CreateOverscroll(0);
				CreateOverscroll(1);
			}
			if (m_ScrollVertical)
			{
				CreateOverscroll(2);
				CreateOverscroll(3);
			}
		}

		private void Update()
		{
			m_ScrollPosition = m_ScrollRect.normalizedPosition;
			if (m_ScrollPosition.x == 0f)
			{
				if (m_LastScrollPosition.x != 0f)
				{
					OnEdgeHit(0);
				}
			}
			else if (m_ScrollPosition.x == 1f)
			{
				if (m_LastScrollPosition.x != 1f)
				{
					OnEdgeHit(1);
				}
			}
			else if (m_LastScrollPosition.x == 1f || m_LastScrollPosition.x == 0f)
			{
				OnEdgeStray(horizontal: true);
			}
			if (m_ScrollPosition.y == 0f)
			{
				if (m_LastScrollPosition.y != 0f)
				{
					OnEdgeHit(3);
				}
			}
			else if (m_ScrollPosition.y == 1f)
			{
				if (m_LastScrollPosition.y != 1f)
				{
					OnEdgeHit(2);
				}
			}
			else if (m_LastScrollPosition.y == 1f || m_LastScrollPosition.y == 0f)
			{
				OnEdgeStray(horizontal: false);
			}
			if (Input.GetMouseButtonUp(0))
			{
				if (m_PointerCount >= 1)
				{
					for (int i = 0; i < 4; i++)
					{
						if ((m_ScrollHorizontal && i <= 1) || (m_ScrollVertical && i >= 2))
						{
							float num = (i > 1) ? m_ScrollPosition.y : m_ScrollPosition.x;
							float num2 = (i != 0 && i != 3) ? 1f : 0f;
							if (m_PointerDown[i] && num == num2)
							{
								m_EdgeAnimsCurrent[i] = m_OverscrollAmounts[i];
								m_EdgeAnimsPower[i] = 0f;
								m_EdgeAnimsStartTime[i] = Time.realtimeSinceStartup;
								m_EdgeAnims[i] = 3;
							}
						}
					}
					for (int j = 0; j < m_PointerDown.Length; j++)
					{
						m_PointerDown[j] = false;
					}
				}
				else
				{
					for (int k = 0; k < 4; k++)
					{
						m_PointerDown[k] = false;
					}
					m_PointerCount = 1;
				}
				m_PointerCount--;
			}
			bool[] array = new bool[4];
			for (int l = 0; l < 4; l++)
			{
				if ((!m_ScrollHorizontal || l > 1) && (!m_ScrollVertical || l < 2))
				{
					continue;
				}
				float num3 = (l > 1) ? m_ScrollPosition.y : m_ScrollPosition.x;
				float num4 = (l != 0 && l != 3) ? 1f : 0f;
				if (m_PointerDown[l] && num3 == num4)
				{
					float num5;
					if (l <= 1)
					{
						Vector3 mousePosition = UnityEngine.Input.mousePosition;
						float y = mousePosition.y;
						Vector3 position = m_RectTransform.position;
						num5 = y - position.y;
					}
					else
					{
						Vector3 mousePosition2 = UnityEngine.Input.mousePosition;
						float x = mousePosition2.x;
						Vector3 position2 = m_RectTransform.position;
						num5 = x - position2.x;
					}
					float num6 = num5;
					float num7 = (l > 1) ? m_Size.x : m_Size.y;
					float num8;
					if (l <= 1)
					{
						Vector3 mousePosition3 = UnityEngine.Input.mousePosition;
						num8 = (mousePosition3.x - m_PointerDownPosition.x) / (float)Screen.width;
					}
					else
					{
						Vector3 mousePosition4 = UnityEngine.Input.mousePosition;
						num8 = (mousePosition4.y - m_PointerDownPosition.y) / (float)Screen.height;
					}
					float num9 = num8;
					num6 = ((!(num6 >= 0f)) ? (0f - Tween.Linear(0f, num7 / 4f, 0f - num6, num7 / 2f)) : Tween.Linear(0f, num7 / 4f, num6, num7 / 2f));
					m_OverscrollPositions[l] = Mathf.Lerp(m_OverscrollPositions[l], num6, Time.deltaTime * 10f);
					if (l == 1 || l == 2)
					{
						num9 *= -1f;
					}
					m_OverscrollAmounts[l] = Mathf.Lerp(m_PointerBaseAmounts[l], num7 / 4f, num9);
					array[l] = false;
				}
				else
				{
					array[l] = true;
				}
			}
			for (int m = 0; m < m_OverscrollRectTransforms.Length; m++)
			{
				if (!array[m])
				{
					continue;
				}
				if (m_EdgeAnims[m] == 1)
				{
					m_EdgeAnimsDeltaTime[m] = Time.realtimeSinceStartup - m_EdgeAnimsStartTime[m];
					if (m_EdgeAnimsDeltaTime[m] < m_EdgeAnimDuration)
					{
						m_OverscrollAmounts[m] = Tween.CubeOut(m_EdgeAnimsCurrent[m], m_EdgeAnimsPower[m], m_EdgeAnimsDeltaTime[m], m_EdgeAnimDuration);
					}
					else
					{
						float num10 = (m > 1) ? m_ScrollPosition.y : m_ScrollPosition.x;
						float num11 = (m != 0 && m != 3) ? 1f : 0f;
						if (num10 == num11)
						{
							m_EdgeAnimsCurrent[m] = m_OverscrollAmounts[m];
							m_EdgeAnimsPower[m] = 0f;
							m_EdgeAnimsStartTime[m] = Time.realtimeSinceStartup;
							m_EdgeAnims[m] = 2;
						}
						else
						{
							m_OverscrollAmounts[m] = m_EdgeAnimsPower[m];
							m_EdgeAnims[m] = 0;
						}
					}
				}
				else if (m_EdgeAnims[m] == 2)
				{
					m_EdgeAnimsDeltaTime[m] = Time.realtimeSinceStartup - m_EdgeAnimsStartTime[m];
					if (m_EdgeAnimsDeltaTime[m] < m_EdgeAnimDuration)
					{
						m_OverscrollAmounts[m] = Tween.CubeIn(m_EdgeAnimsCurrent[m], m_EdgeAnimsPower[m], m_EdgeAnimsDeltaTime[m], m_EdgeAnimDuration);
					}
					else
					{
						m_OverscrollAmounts[m] = m_EdgeAnimsPower[m];
						m_EdgeAnims[m] = 0;
					}
				}
				else if (m_EdgeAnims[m] == 3)
				{
					m_EdgeAnimsDeltaTime[m] = Time.realtimeSinceStartup - m_EdgeAnimsStartTime[m];
					if (m_EdgeAnimsDeltaTime[m] < m_EdgeAnimDuration * 2f)
					{
						m_OverscrollAmounts[m] = Tween.CubeIn(m_EdgeAnimsCurrent[m], m_EdgeAnimsPower[m], m_EdgeAnimsDeltaTime[m], m_EdgeAnimDuration * 2f);
					}
					else
					{
						m_OverscrollAmounts[m] = m_EdgeAnimsPower[m];
						m_EdgeAnims[m] = 0;
					}
				}
				m_OverscrollPositions[m] = Mathf.Lerp(m_OverscrollPositions[m], 0f, Time.deltaTime);
			}
			for (int n = 0; n < m_OverscrollRectTransforms.Length; n++)
			{
				if ((m_ScrollHorizontal && n <= 1) || (m_ScrollVertical && n >= 2))
				{
					Vector2 anchoredPosition = (n > 1) ? new Vector2(m_OverscrollPositions[n], 0f) : new Vector2(0f, m_OverscrollPositions[n]);
					float num12 = (n > 1) ? m_Size.x : m_Size.y;
					m_OverscrollRectTransforms[n].anchoredPosition = anchoredPosition;
					m_OverscrollRectTransforms[n].sizeDelta = new Vector2(num12 * 1.5f, m_OverscrollAmounts[n] * m_OverscrollScale);
					m_LastScrollPosition = m_ScrollPosition;
					m_OverscrollImages[n].color = m_OverscrollColor.WithAlpha(m_OverscrollAmounts[n] / (num12 / 4f) * m_OverscrollColor.a);
				}
			}
		}

		private void OnEdgeHit(int edge)
		{
			if (m_PointerDown[edge])
			{
				SetupPointer(edge);
				return;
			}
			float num = (edge > 1) ? m_Size.x : m_Size.y;
			float num2;
			if (edge <= 1)
			{
				Vector2 velocity = m_ScrollRect.velocity;
				num2 = velocity.x;
			}
			else
			{
				Vector2 velocity2 = m_ScrollRect.velocity;
				num2 = velocity2.y;
			}
			float num3 = num2;
			if (edge == 1 || edge == 2)
			{
				num3 *= -1f;
			}
			m_EdgeAnimsCurrent[edge] = m_OverscrollAmounts[edge];
			m_EdgeAnimsPower[edge] = Mathf.Lerp(0f, num / 4f, Mathf.Sqrt(num3) / 65f);
			m_EdgeAnimsStartTime[edge] = Time.realtimeSinceStartup;
			m_EdgeAnims[edge] = 1;
		}

		private void OnEdgeStray(bool horizontal)
		{
			for (int i = 0; i < m_OverscrollRectTransforms.Length; i++)
			{
				if ((horizontal && i <= 1) || (!horizontal && i >= 2))
				{
					m_EdgeAnimsCurrent[i] = m_OverscrollAmounts[i];
					m_EdgeAnimsPower[i] = 0f;
					m_EdgeAnimsStartTime[i] = Time.realtimeSinceStartup;
					m_EdgeAnims[i] = 2;
				}
			}
		}

		private void SetupPointer(int edge)
		{
			if (edge == -1)
			{
				for (int i = 0; i < m_OverscrollRectTransforms.Length; i++)
				{
					m_PointerDown[i] = true;
					m_EdgeAnims[i] = 0;
					m_PointerDownPosition = UnityEngine.Input.mousePosition;
					m_PointerBaseAmounts[i] = m_OverscrollAmounts[i];
				}
			}
			else
			{
				m_PointerDown[edge] = true;
				m_EdgeAnims[edge] = 0;
				m_PointerDownPosition = UnityEngine.Input.mousePosition;
				m_PointerBaseAmounts[edge] = m_OverscrollAmounts[edge];
			}
		}

		private IEnumerator GetDelayedSize()
		{
			VerticalScrollLayoutElement verticalScrollLayoutElement = GetComponent<VerticalScrollLayoutElement>();
			verticalScrollLayoutElement.CalculateLayoutInputVertical();
			yield return new WaitForEndOfFrame();
			m_Size = m_RectTransform.GetProperSize();
			if (!verticalScrollLayoutElement.scrollEnabled)
			{
				base.enabled = false;
			}
		}

		public void OnInitializePotentialDrag(PointerEventData eventData)
		{
			if (m_PointerCount <= 0)
			{
				SetupPointer(-1);
			}
			m_PointerCount++;
		}
	}
}
